#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include <pthread.h>
#include "include/cal.h"
#include "include/filesystem.h"
#include "include/sysutils.h"
#include "include/vehicle.h"
#include "include/stn.h"
#include "include/sound.h"


struct trip_status tstatus;
struct car_data cdata;
struct cal_result rdata;
struct min_data mdata;
struct summary_data sdata;
struct obd_data odata;

void init_Trip(struct trip_status *t)
{
	pthread_mutex_init(&t->lock, NULL);
	t->tripstatus = 0;
	t->min_index = 0;
}

void init_OBD_DATA(struct obd_data *o)
{
	pthread_mutex_init(&o->lock, NULL);
	memset(o->data, 0, SEC_DATA_LEN);
}

void init_CAL(struct car_data *c, struct min_data *m, struct summary_data *s)
{

	/* initial car_data */
	pthread_mutex_init(&c->lock, NULL);
	c->writepos = 0;
	c->readpos = 0;
	pthread_cond_init(&c->notempty, NULL);
	pthread_cond_init(&c->notfull, NULL);

	/* initial min_data */
	pthread_mutex_init(&m->lock, NULL);
	m->data_type = 0x01;
	m->data_len = MDATA_LEN;
	m->top_speed = 0;
	m->best_fuel_rate = 0;
	m->best_speed = 0;
	m->dist_h = 0;
	m->dist_l = 0;
	m->avg_speed = 0;
	m->avg_rpm_h = 0;
	m->avg_rpm_l = 0;
	m->max_rpm_h = 0;
	m->max_rpm_l = 0;
	m->total_fuel = 0;
	m->avg_fuel_h = 0;
	m->avg_fuel_l = 0;
	m->cal_load = 0;
	m->cool_temp = 0;
	m->pad_pos = 0;
	m->pad_pos_max = 0;
	m->pad_pos_min = 0;
	//m->fuel_lv = 0xFF;
	m->acc_num = 0;
	m->brk_num = 0;
	m->over_spd = 0;
	m->idel_spd = 0;
	m->sliding = 0;	
	pthread_cond_init(&m->dataok, NULL);

	/* initial summary_data */
	pthread_mutex_init(&s->lock, NULL);
	//s->file_index = 0x80000000;
	s->data_type = 0x02;
	s->data_len = SDATA_LEN;
	s->trip_time = 0;
	s->air_pressure = 0xFF;
	//s->fuel_lv = 0xFF;
	s->bat = 0;
	s->err_dist_h = 0xFF;
	s->err_dist_l = 0xFF;
	s->clr_dist_h = 0xFF;
	s->clr_dist_l = 0xFF;
	s->temp = 0;
	s->dist_h = 0;
	s->dist_l = 0;
	s->trip_top_speed = 0;
	s->best_fuel_rate = 0;
	s->trip_best_speed = 0;
	s->trip_total_fuel_h = 0;
	s->trip_total_fuel_l = 0;
	s->trip_avg_fuel_h = 0;
	s->trip_avg_fuel_l = 0;
	//s->last_fuel_lv = 0xFF;
	s->avg_cool_temp = 0;
	s->max_cool_temp = 0;
	s->pad_pos = 0;
	s->pad_pos_max = 0;
	s->pad_pos_min = 0;
	s->trip_avg_rpm_h = 0;
	s->trip_avg_rpm_l = 0;
	s->trip_max_rpm_h = 0;
	s->trip_max_rpm_l = 0;
	s->trip_acc_cnt = 0;
	s->trip_brk_cnt = 0;
	s->trip_over_spd = 0;
	s->trip_idel_spd = 0;
	s->trip_sliding = 0;
	s->fast_time = 0;
	s->slow_time = 0;
	s->jam_time = 0;
	s->dtc_num = 0;
	pthread_cond_init(&s->dataok, NULL);
}

void updateOBDDATA(struct obd_data *o, int data, int index)
{
	pthread_mutex_lock(&o->lock);
	o->data[index] = data;
	pthread_mutex_unlock(&o->lock);
}

void updateFileIndex(struct summary_data *s, int index)
{
	pthread_mutex_lock(&s->lock);
	s->file_index = index;
	pthread_mutex_unlock(&s->lock);
}

int getFileIndex(struct summary_data *s)
{
	int ret;
	pthread_mutex_lock(&s->lock);
	ret = s->file_index;
	pthread_mutex_unlock(&s->lock);
	return ret;
}

/*将OBD实时数据切片存入待计算缓存*/
void saveCarData(struct car_data *c, int *data)
{
	int i;
	pthread_mutex_lock(&c->lock);
	/* Wait until buffer is not full */
	while ((c->writepos + 1) % SEC_BUF_SIZE == c->readpos) {
		printf("put_cardata_wait_condition!\n");
	   pthread_cond_wait(&c->notfull, &c->lock);
   /* pthread_cond_wait reacquired c->lock before returning */
	}
  /* Write the data and advance write pointer */
	for(i = 0; i < SEC_DATA_LEN; i++)  
		c->sec_data[(c->writepos * SEC_DATA_LEN) +i] = *(data+i);
  
	c->writepos++;
  	if (c->writepos >= SEC_BUF_SIZE) c->writepos = 0;
  /* Signal that the buffer is now not empty */
  pthread_cond_signal(&c->notempty);
  pthread_mutex_unlock(&c->lock);
}

/*从待计算缓存中读出数据切片*/
void readCarData(struct car_data *c, int *data)
{
	int i;
	pthread_mutex_lock(&c->lock);
	/* Wait until buffer is not empty */
	while (c->writepos == c->readpos) {
		//printf("get_cardata_wait_condition!\n");
		pthread_cond_wait(&c->notempty, &c->lock);
  	}
  /* Read the data and advance read pointer */
	for(i = 0;i < SEC_DATA_LEN;i++)  
		*(data + i) = c->sec_data[(c->readpos * SEC_DATA_LEN) + i];
  c->readpos++;
  if (c->readpos >= SEC_BUF_SIZE) c->readpos = 0;
  /* Signal that the buffer is now not full */
  pthread_cond_signal(&c->notfull);
  pthread_mutex_unlock(&c->lock);
}

/*计算每分钟累计数据*/
void calMinData(struct cal_result *r,  int count, int *data)
{	
	int index;
	int speed_total = 0;
	int rpm_total = 0;
	int cal_load_total = 0;
	int cool_temp_total = 0;
	int pad_pos_total = 0;

	unsigned long fuel_total  = 0;
	unsigned long fuel_avg = 0;

	int acc_count = 0;
	int acc_start = 0;
	int brk_count = 0;

	/* Vehicle Parameter */ 
	//初始化
	r->speed_top = data[OBD_DATA_SPD];
	r->speed_avg = 0;
	r->rpm_avg = 0;
	r->rpm_max = data[OBD_DATA_RPM];
	r->fuel_total = 0;
	r->fuel_avg = 0;
	r->cal_load = 0;
	r->cool_temp = 0;
	r->pad_pos = 0;
	r->pad_pos_max = data[OBD_DATA_PAD];
	r->pad_pos_min = data[OBD_DATA_PAD];
	r->dist = 0;
	r->best_fuel_rate = 0;
	r->best_speed = 0;

	/* Drive Behavior */
	//初始化
	r->acc_num = 0;
	r->brk_num = 0;
	r->over_spd = 0;
	r->idel_spd = 0;
	r->sliding = 0;

	for(index = 0; index < count; index++){
		//  累计 速度
		speed_total += data[index * SEC_DATA_LEN + OBD_DATA_SPD];
		// 累计转速
		rpm_total += data[index * SEC_DATA_LEN + OBD_DATA_RPM];

		// 累计耗油量	
		fuel_total += data[index * SEC_DATA_LEN + OBD_DATA_FR]; // 结果整数中有4位小数

		// 累计发动机负载
		cal_load_total += data[index * SEC_DATA_LEN + OBD_DATA_EL];
		// 累计水箱温度
		cool_temp_total += data[index * SEC_DATA_LEN + OBD_DATA_CT];
		// 累计节气门位置
		pad_pos_total += data[index * SEC_DATA_LEN + OBD_DATA_PAD];
		
		/* Cal Best Fuel Rate @ Best Speed */
		//条件：速度大于0并且节气门位置大于0，即非停止或滑行状态
		if( data[index * SEC_DATA_LEN+ OBD_DATA_SPD] > 0 
					&& data[index * SEC_DATA_LEN + OBD_DATA_PAD] > 0){
			if( data[index * SEC_DATA_LEN + OBD_DATA_FR100] < r->best_fuel_rate )
				r->best_speed = data[index * SEC_DATA_LEN];
				//修改时间： 2013/10/08
				//修改人： Ray Goo
				//修改原因： 由于在秒级的运算中已经去除了百公里油耗的计算，所以在此处最佳油耗选择记录耗油量
				//r->best_fuel_rate = data[index * SEC_DATA_LEN + OBD_DATA_FR100];	//从瞬时油耗中获得
				r->best_fuel_rate = data[index * SEC_DATA_LEN + OBD_DATA_FR] / 10; // 保留 3位小数
		}

		/* Cal Top Speed */
		if( data[index*SEC_DATA_LEN] > r->speed_top ) 
			r->speed_top = data[index * SEC_DATA_LEN];
		
		/* Cal Max RPM */
		if( data[index*SEC_DATA_LEN + OBD_DATA_RPM] > r->rpm_max ) 
			r->rpm_max = data[index * SEC_DATA_LEN + OBD_DATA_RPM];
		
		/* Cal Max Pad Position */
		if( data[index*SEC_DATA_LEN + OBD_DATA_PAD] > r->pad_pos_max ) 
			r->pad_pos_max = data[index * SEC_DATA_LEN + OBD_DATA_PAD];

		/* Cal Min Pad Position */
		if( data[index*SEC_DATA_LEN + OBD_DATA_PAD] < r->pad_pos_min ) 
			r->pad_pos_min = data[index * SEC_DATA_LEN + OBD_DATA_PAD];

		/* Cal Rapid ACC Times */
		if( data[index * SEC_DATA_LEN] > ACCSPEED){
			if(acc_start == 0){
				if( data[index*SEC_DATA_LEN + OBD_DATA_PAD] > r->pad_pos_min + ACCPADPOS ){
					acc_start = 1;
					acc_count++;
				}
			}
			else{
				if( data[index*SEC_DATA_LEN + OBD_DATA_PAD] > r->pad_pos_min + ACCPADPOS ){
					acc_count++;
				}
				else{
					acc_start = 0;
					if(acc_count > 3) {
						//play sound of ENGINE Start
						saveSoundList(&sl, SOUND_ACC_INDEX,Sound_status);
						r->acc_num++;
					}
				}
			}
		}

		/* Cal Rapid BRK Times */
		if(	data[index * SEC_DATA_LEN] > BRKSPEED	){
			/* TBD */
			//play sound of ENGINE Start
			saveSoundList(&sl, SOUND_BRK_INDEX, Sound_status);

		}

		/* Cal Over Speed Time */
		if(data[index*SEC_DATA_LEN] > OVERSPEED)
			r->over_spd++;

		/* Cal Idel Speed Time */
		if( data[index*SEC_DATA_LEN] == IDELSPEED )
			r->idel_spd++;
		
		/* Cal Sliding Time */
		if(data[index*SEC_DATA_LEN + OBD_DATA_SPD] >= 25 && \
				data[index*SEC_DATA_LEN + OBD_DATA_PAD] < r->pad_pos_min + SLIDINGPOS)
			r->sliding++;
		
	}
	/* Cal Average of Vehicle Speed */	
	r->speed_avg = speed_total / count;

	/* Cal Average of Engine RPM */
	r->rpm_avg = rpm_total / count;

	/* Cal Average of Engine Load */
	r->cal_load = cal_load_total / count;

	/* Cal Average of Cool temperature */
	r->cool_temp =  cool_temp_total / count;

	/* Cal Average of Pad position */
	r->pad_pos = pad_pos_total / count;

	/* Cal Distance in a minitue */
	//时速转化成 m/s后， 该分钟累计的速度就是行驶里程，单位 m
	r->dist = speed_total * 1000 / 3600;      

	/*计算该分钟总油耗*/
	r->fuel_total =(int)(fuel_total / 10000);    // 单位ml

	/* Cal FuelRate of 100KM in Distance Methord */
	// 当 该分钟中累计速度为0的时候，平均百公里油耗设定为50L
	if(speed_total == 0) r->fuel_avg = 5000; 
	else{
		//计算该分钟百公里油耗
		//公式： 总油耗L * 100 / 里程KM
		//总油耗（L）：  (fuel_total / 1000)  （其中fuel_total单位为ml,整数中含4位小数）
		//里程（KM）：   speed_total / 3600
		//公式推导百公里油耗：  fuel_avg = （fuel_total * 36） * 10 / speed_total
		//结果保留两位小数：  fuel_avg = (（fuel_total * 36） / speed_total ) / 10
		fuel_avg = fuel_total * 36; 
		fuel_avg /= speed_total;
		r->fuel_avg = (int)(fuel_avg / 10);    // 结果L/100km 整数中保留2位小数
	}
}

/*更新分钟数据切片中的油箱存量*/
void updateMinFuellv(struct min_data *m, unsigned char value)
{
	pthread_mutex_lock(&m->lock);
	m->fuel_lv = value;
	pthread_mutex_unlock(&m->lock);
}

/*更新分钟数据切片中的GPS信息*/
void updateMinGPS(struct min_data *m, unsigned char *data)
{
	pthread_mutex_lock(&m->lock);
	m->lat_dd = data[0];
	m->lat_mm1 = data[1];
	m->lat_mm2 = data[2];
	m->lat_mm3 = data[3];
	m->ns = data[4];
	m->long_0d = data[5];
	m->long_dd = data[6];
	m->long_mm1 = data[7];
	m->long_mm2 = data[8];
	m->long_mm3 = data[9];
	m->ew = data[10];
	m->ele_h = data[11];
	m->ele_l = data[12];
	pthread_mutex_unlock(&m->lock);
}

/*更新分钟数据切片的日期时间信息*/
void updateMinTime(struct min_data *m, unsigned char *data)
{
	pthread_mutex_lock(&m->lock);
	m->date_yy = data[0];
	m->date_mm = data[1];
	m->date_dd = data[2];
	m->time_hh = data[3];
	m->time_mm = data[4];
	m->time_ss = data[5];
	pthread_mutex_unlock(&m->lock);	
}

/*转换分钟数据切片的数据类型为最终输出的数据类型*/
void convertMinData(struct cal_result *r, struct min_data *m)
{
	pthread_mutex_lock(&m->lock);
	m->top_speed = 	(unsigned char)(r->speed_top);

	m->best_fuel_rate = (unsigned char)(r->best_fuel_rate / 10);	// 保留2位小数
	m->best_speed = (unsigned char)(r->best_speed);

	m->dist_h = (unsigned char)( (r->dist & 0xFF00) / 256 );
	m->dist_l = (unsigned char)(r->dist % 256);

	m->avg_speed = (unsigned char)(r->speed_avg);
	
	m->avg_rpm_h = (unsigned char)( (r->rpm_avg & 0xFF00) / 256 );
	m->avg_rpm_l = (unsigned char)(r->rpm_avg % 256);

	m->max_rpm_h = (unsigned char)( (r->rpm_max & 0xFF00) / 256 );
	m->max_rpm_l = (unsigned char)(r->rpm_max % 256);

	m->total_fuel = (unsigned char)(r->fuel_total);
	m->avg_fuel_h = (unsigned char)((r->fuel_avg & 0xFF00) / 256);
	m->avg_fuel_l = (unsigned char)(r->fuel_avg % 256);

	m->cal_load = (unsigned char)(r->cal_load);
	m->cool_temp = (unsigned char)(r->cool_temp);

	m->pad_pos = (unsigned char)(r->pad_pos);
	m->pad_pos_max = (unsigned char)(r->pad_pos_max);
	m->pad_pos_min = (unsigned char)(r->pad_pos_min);

	m->acc_num = (unsigned char)(r->acc_num);
	m->brk_num = (unsigned char)(r->brk_num);
	
	m->over_spd = (unsigned char)(r->over_spd);
	m->idel_spd = (unsigned char)(r->idel_spd);
	m->sliding = (unsigned char)(r->sliding);

	pthread_mutex_unlock(&m->lock);
}

/*将分钟数据切片按最终保存格式存储在缓冲中*/
void storeMinDataToTrip(struct min_data *m, unsigned char *t, int index)
{
	pthread_mutex_lock(&m->lock);
	t[index * MDATA_LEN] = m->data_type;
	t[index * MDATA_LEN + 1] = m->data_len;
	t[index * MDATA_LEN + 2] = m->date_yy;
	t[index * MDATA_LEN + 3] = m->date_mm;
	t[index * MDATA_LEN + 4] = m->date_dd;
	t[index * MDATA_LEN + 5] = m->time_hh;
	t[index * MDATA_LEN + 6] = m->time_mm;
	t[index * MDATA_LEN + 7] = m->time_ss;
	t[index * MDATA_LEN + 8] = m->lat_dd;
	t[index * MDATA_LEN + 9] = m->lat_mm1;
	t[index * MDATA_LEN + 10] = m->lat_mm2;
	t[index * MDATA_LEN + 11] = m->lat_mm3;
	t[index * MDATA_LEN + 12] = m->ns;
	t[index * MDATA_LEN + 13] = m->long_0d;
	t[index * MDATA_LEN + 14] = m->long_dd;
	t[index * MDATA_LEN + 15] = m->long_mm1;
	t[index * MDATA_LEN + 16] = m->long_mm2;
	t[index * MDATA_LEN + 17] = m->long_mm3;
	t[index * MDATA_LEN + 18] = m->ew;
	t[index * MDATA_LEN + 19] = m->ele_h;
	t[index * MDATA_LEN + 20] = m->ele_l;
	t[index * MDATA_LEN + 21] = m->top_speed;
	t[index * MDATA_LEN + 22] = m->best_fuel_rate;
	t[index * MDATA_LEN + 23] = m->best_speed;
	t[index * MDATA_LEN + 24] = m->dist_h;
	t[index * MDATA_LEN + 25] = m->dist_l;
	t[index * MDATA_LEN + 26] = m->avg_speed;
	t[index * MDATA_LEN + 27] = m->avg_rpm_h;
	t[index * MDATA_LEN + 28] = m->avg_rpm_l;
	t[index * MDATA_LEN + 29] = m->max_rpm_h;
	t[index * MDATA_LEN + 30] = m->max_rpm_l;
	t[index * MDATA_LEN + 31] = m->total_fuel;
	t[index * MDATA_LEN + 32] = m->avg_fuel_h;
	t[index * MDATA_LEN + 33] = m->avg_fuel_l;
	t[index * MDATA_LEN + 34] = m->cal_load;
	t[index * MDATA_LEN + 35] = m->cool_temp;
	t[index * MDATA_LEN + 36] = m->pad_pos;
	t[index * MDATA_LEN + 37] = m->pad_pos_max;
	t[index * MDATA_LEN + 38] = m->pad_pos_min;
	t[index * MDATA_LEN + 39] = m->fuel_lv;
	t[index * MDATA_LEN + 40] = m->acc_num;
	t[index * MDATA_LEN + 41] = m->brk_num;
	t[index * MDATA_LEN + 42] = m->over_spd;
	t[index * MDATA_LEN + 43] = m->idel_spd;
	t[index * MDATA_LEN + 44] = m->sliding;
	pthread_mutex_unlock(&m->lock);
}

/*启动行程数据记录*/
void startTripDataRecord(struct trip_status *t)
{
	pthread_mutex_lock(&t->lock);
	t->tripstatus = 1;
	pthread_mutex_unlock(&t->lock);
}

/*停止行程数据记录*/
void stopTripDataRecord(struct trip_status *t)
{
	pthread_mutex_lock(&t->lock);
	t->tripstatus = 0;
	pthread_mutex_unlock(&t->lock);
}

/*获取行程数据记录状态*/
// 返回0： 记录停止
//返回1： 记录进行中
int getTripStatus(struct trip_status *t)
{
	int ret;
	pthread_mutex_lock(&t->lock);
	ret = t->tripstatus;
	pthread_mutex_unlock(&t->lock);
	return ret;
}

/*分钟级数据切片记录索引号累加1*/
void increaseMinIndex(struct trip_status *t)
{
	pthread_mutex_lock(&t->lock);
	t->min_index++;
	pthread_mutex_unlock(&t->lock);
}

/*清除归零分钟级数据切片索引号*/
void clearMinIndex(struct trip_status *t)
{
	pthread_mutex_lock(&t->lock);
	t->min_index = 0;
	pthread_mutex_unlock(&t->lock);
}

/*获取分钟级数据切片索引号*/
int getMinIndex(struct trip_status *t)
{
	int ret;
	pthread_mutex_lock(&t->lock);
	ret = t->min_index;
	pthread_mutex_unlock(&t->lock);
	return ret;
}

/*保存DTC信息*/
void setDTCData(struct trip_status *t, unsigned char *data, int count)
{
	int i;
	pthread_mutex_lock(&t->lock);
	t->min_index = count;
	for(i = 0; i< count * DTC_LEN; i++)
		t->dtc_data[i] = data[i];
	t->dtc_data[count * DTC_LEN] = (unsigned char)(count);
	pthread_mutex_unlock(&t->lock);
}

/*更新DTC数量*/
int getDTCnum(struct trip_status *t)
{
	int ret;
	pthread_mutex_lock(&t->lock);
	ret = t->dtc_num;
	pthread_mutex_unlock(&t->lock);
	return ret;
}

/*更新行程Summary中开始日期时间*/
void updateSummaryTimeStart(struct summary_data *s, unsigned char *data)
{
	pthread_mutex_lock(&s->lock);
	s->start_date_yy = data[0];
	s->start_date_mm = data[1];
	s->start_date_dd = data[2];
	s->start_time_hh = data[3];
	s->start_time_mm = data[4];
	s->start_time_ss = data[5];
	pthread_mutex_unlock(&s->lock);
}

/*更新行程Summary中结束日期时间*/
void updateSummaryTimeEnd(struct summary_data *s, unsigned char *data)
{
	pthread_mutex_lock(&s->lock);
	s->end_date_yy = data[0];
	s->end_date_mm = data[1];
	s->end_date_dd = data[2];
	s->end_time_hh = data[3];
	s->end_time_mm = data[4];
	s->end_time_ss = data[5];
	pthread_mutex_unlock(&s->lock);
}

/*更新行程Summary中开始GPS信息*/
void updateSummaryGPSStart(struct summary_data *s, unsigned char * data)
{
	pthread_mutex_lock(&s->lock);
	s->start_lat_dd = data[0];
	s->start_lat_mm1 = data[1];
	s->start_lat_mm2 = data[2];
	s->start_lat_mm3 = data[3];
	s->start_ns = data[4];
	s->start_long_0d = data[5];
	s->start_long_dd = data[6];
	s->start_long_mm1 = data[7];
	s->start_long_mm2 = data[8];
	s->start_long_mm3 = data[9];
	s->start_ew = data[10];
	s->start_ele_h = data[11];
	s->start_ele_l = data[12];
	pthread_mutex_unlock(&s->lock);
}

/*更新行程Summary中结束GPS信息*/
void updateSummaryGPSEnd(struct summary_data *s, unsigned char * data)
{
	pthread_mutex_lock(&s->lock);
	s->end_lat_dd = data[0];
	s->end_lat_mm1 = data[1];
	s->end_lat_mm2 = data[2];
	s->end_lat_mm3 = data[3];
	s->end_ns = data[4];
	s->end_long_0d = data[5];
	s->end_long_dd = data[6];
	s->end_long_mm1 = data[7];
	s->end_long_mm2 = data[8];
	s->end_long_mm3 = data[9];
	s->end_ew = data[10];
	s->end_ele_h = data[11];
	s->end_ele_l = data[12];
	pthread_mutex_unlock(&s->lock);
}

/*更新Summary中电池电量数据*/
void updateSummaryBat(struct summary_data *s, unsigned char bat)
{
	pthread_mutex_lock(&s->lock);
	s->bat = bat;
	pthread_mutex_unlock(&s->lock);
}

/*更新最后存油*/
void updateSummaryFuelLV(struct summary_data *s, unsigned char value)
{
	pthread_mutex_lock(&s->lock);
	s->fuel_lv = value;
	pthread_mutex_unlock(&s->lock);
}

/*更新最后存油*/
void updateSummaryLastFuelLV(struct summary_data *s, unsigned char value)
{
	pthread_mutex_lock(&s->lock);
	s->last_fuel_lv = value;
	pthread_mutex_unlock(&s->lock);
}

/*计算行程Summary中数据*/
void createTripSummary(struct summary_data *s, unsigned char *t, int count, \
								int fast_time, int slow_time, int jam_time)
{
	int i;
	int trip_dist = 0;
	unsigned long trip_fuel = 0;
	int trip_avg_fuel_total = 0;
	int avg_cool_temp_total = 0;
	int pad_pos_total = 0;
	int trip_rpm_total = 0;
	int trip_rpm_avg = 0;
	int trip_max_rpm = 0;
	int trip_max_rpm_tmp = 0;
	int overspdtime = 0;
	int idelspdtime = 0;
	int slidingtime = 0;
	int total_sec = fast_time + slow_time + jam_time;


	pthread_mutex_lock(&s->lock);
	
	s->err_dist_h;	
	s->err_dist_l;
	s->clr_dist_h;
	s->clr_dist_l;	
	s->temp = 0xFF;
	
	s->trip_time = (unsigned char) count;
	s->trip_top_speed = t[21];
	s->best_fuel_rate = t[22];
	s->trip_best_speed = t[23];
	//s->last_fuel_lv = 0xFF;
	s->max_cool_temp = t[35];
	s->pad_pos_max = t[37];
	s->pad_pos_min = t[38];
	trip_max_rpm = t[29]*256 + t[30];
	s->trip_acc_cnt = 0;
	s->trip_brk_cnt = 0;
	
	//快速行驶百分比
	s->fast_time = (unsigned char)(fast_time * 100 / total_sec);
	//慢速行驶百分比 	
	s->slow_time = (unsigned char)(slow_time * 100 / total_sec);
	//堵车时间百分比
	s->jam_time = 100 - s->fast_time - s->slow_time;
	//错误代码数量
	s->dtc_num = 0;
	
	for(i = 0; i < count; i++){

		//累计行驶距离
		trip_dist += (t[i*MDATA_LEN + 24] * 256 + t[i*MDATA_LEN + 25]);
		
		//记录最高车速
		if(s->trip_top_speed < t[i*MDATA_LEN + 21]) s->trip_top_speed = t[i*MDATA_LEN + 21];
		
		//记录最佳燃油率 及所对应的最佳行驶速度
		if(s->best_fuel_rate > t[i*MDATA_LEN + 22]){
			s->best_fuel_rate = t[i*MDATA_LEN + 22];
			s->trip_best_speed = t[i*MDATA_LEN + 23];
		}
		//累计耗油量
		trip_fuel += t[i*MDATA_LEN + 31];

		//累计平均油耗
		//修改日期： 2013/10/10
		//修改人： Ray Goo
		//修改原因： 行程百公里油耗的计算方法用总耗油量/里程来计算，所以取消原先平均每分钟的百公里油耗计算方法
		//trip_avg_fuel_total += t[i*MDATA_LEN + 32] * 256 + t[i*MDATA_LEN + 33];
		
		//累计水箱温度
		avg_cool_temp_total += t[i*MDATA_LEN + 35];

		//记录最高水箱温度
		if(s->max_cool_temp < t[i*MDATA_LEN + 35]) s->max_cool_temp = t[i*MDATA_LEN + 35];
		
		//累计节气门位置
		pad_pos_total += t[i*MDATA_LEN + 36];	
		//记录最大节气门位置
		if(s->pad_pos_max < t[i*MDATA_LEN + 37])  s->pad_pos_max = t[i*MDATA_LEN + 37];
		//记录最小节气门位置
		if(s->pad_pos_min > t[i*MDATA_LEN + 38])  s->pad_pos_min = t[i*MDATA_LEN + 38];
	
		//累计转速
		trip_rpm_total += (t[i*MDATA_LEN + 27] * 256 + t[i*MDATA_LEN + 28]);
		
		//记录最大转速
		trip_max_rpm_tmp = (t[i*MDATA_LEN + 29] * 256 + t[i*MDATA_LEN + 30]);
		if(trip_max_rpm < trip_max_rpm_tmp) trip_max_rpm = trip_max_rpm_tmp;
		
		//累计急加速次数
		s->trip_acc_cnt += t[i*MDATA_LEN + 40];
		//累计急刹车次数
		s->trip_brk_cnt += t[i*MDATA_LEN + 41];

		//累计超速时间
		overspdtime += t[i*MDATA_LEN + 42];
		//累计怠速时间
		idelspdtime += t[i*MDATA_LEN + 43];
		//累计滑行时间
		slidingtime += t[i*MDATA_LEN + 44];
	}

	//行程距离
	s->dist_h = (unsigned char)(((trip_dist/10) & 0xFF00) / 256);
	s->dist_l = (unsigned char)((trip_dist/10) % 256);
	
	//行程总耗油量
	s->trip_total_fuel_h = (unsigned char)((trip_fuel & 0xFF00) / 256 );
	s->trip_total_fuel_l = (unsigned char)(trip_fuel % 256);
 	
	//平均百公里油耗
	// 此处2013年10月8日修改为 （总耗油量 / 行程距离） * 100
	// 公式  ( (trip_fuel / 1000) / (trip_dist / 1000)  ) * 100   其中 trip_fuel 单位：ml, trip_dist 单位：m
	//公式转变为：  trip_fuel * 100 / trip_dist

	//trip_avg_fuel_total /= count;

	trip_fuel *= 100*100;   // 第一个100是计算百公里油耗，第二个100是数值中保留2位小数
	trip_avg_fuel_total = (unsigned int)(trip_fuel / trip_dist);
	s->trip_avg_fuel_h = (unsigned char)((trip_avg_fuel_total & 0xFF00) / 256);
	s->trip_avg_fuel_l = (unsigned char)(trip_avg_fuel_total % 256);	
	
	//平均水箱温度
	s->avg_cool_temp = (unsigned char)(avg_cool_temp_total / count);
	
	//平均节气门温度	
	s->pad_pos = (unsigned char)(pad_pos_total / count);
	
	//平均转速
	trip_rpm_avg = (trip_rpm_total / count);
	s->trip_avg_rpm_h = (unsigned char)( (trip_rpm_avg & 0xFF00) / 256 );
	s->trip_avg_rpm_l = (unsigned char)( trip_rpm_avg % 256 );
	
	//最大转速
	s->trip_max_rpm_h = (unsigned char)( (trip_max_rpm & 0xFF00) / 256 );
	s->trip_max_rpm_l = (unsigned char)( trip_max_rpm % 256 );	
	
	//超速百分比
	s->trip_over_spd = (unsigned char)(overspdtime * 100 / total_sec);
	//怠速百分比	
	s->trip_idel_spd = (unsigned char)(idelspdtime * 100 / total_sec);
	//滑行百分比	
	s->trip_sliding = (unsigned char)(slidingtime * 100 / total_sec);
	pthread_mutex_unlock(&s->lock);

}

/*将数据填入Summary缓存*/
void storeSummaryDataToTrip(struct summary_data * s, unsigned char * t)
{
	pthread_mutex_lock(&s->lock);
	t[0] = s->data_type;
	t[1] = s->data_len;
	t[2] = s->start_date_yy;
	t[3] = s->start_date_mm;
	t[4] = s->start_date_dd;
	t[5] = s->start_time_hh;
	t[6] = s->start_time_mm;
	t[7] = s->start_time_ss;
	t[8] = s->start_lat_dd;
	t[9] = s->start_lat_mm1;
	t[10] = s->start_lat_mm2;
	t[11] = s->start_lat_mm3;
	t[12] = s->start_ns;
	t[13] = s->start_long_0d;
	t[14] = s->start_long_dd;
	t[15] = s->start_long_mm1;
	t[16] = s->start_long_mm2;
	t[17] = s->start_long_mm3;
	t[18] = s->start_ew;
	t[19] = s->start_ele_h;
	t[20] = s->start_ele_l;
	t[21] = s->end_date_yy;
	t[22] = s->end_date_mm;
	t[23] = s->end_date_dd;
	t[24] = s->end_time_hh;
	t[25] = s->end_time_mm;
	t[26] = s->end_time_ss;
	t[27] = s->end_lat_dd;
	t[28] = s->end_lat_mm1;
	t[29] = s->end_lat_mm2;
	t[30] = s->end_lat_mm3;
	t[31] = s->end_ns;
	t[32] = s->end_long_0d;
	t[33] = s->end_long_dd;
	t[34] = s->end_long_mm1;
	t[35] = s->end_long_mm2;
	t[36] = s->end_long_mm3;
	t[37] = s->end_ew;
	t[38] = s->end_ele_h;
	t[39] = s->end_ele_l;
	t[40] = s->trip_time;
	t[41] = s->air_pressure;
	t[42] = s->fuel_lv;
	t[43] = s->bat;
	t[44] = s->err_dist_h;
	t[45] = s->err_dist_l;
	t[46] = s->clr_dist_h;
	t[47] = s->clr_dist_l;
	t[48] = s->temp;
	t[49] = s->dist_h;
	t[50] = s->dist_l;
	t[51] = s->trip_top_speed;
	t[52] = s->best_fuel_rate;
	t[53] = s->trip_best_speed;
	t[54] = s->trip_total_fuel_h;
	t[55] = s->trip_total_fuel_l;
	t[56] = s->trip_avg_fuel_h;
	t[57] = s->trip_avg_fuel_l;
	t[58] = s->last_fuel_lv;
	t[59] = s->avg_cool_temp;
	t[60] = s->max_cool_temp;
	t[61] = s->pad_pos;
	t[62] = s->pad_pos_max;
	t[63] = s->pad_pos_min;
	t[64] = s->trip_avg_rpm_h;
	t[65] = s->trip_avg_rpm_l;
	t[66] = s->trip_max_rpm_h;
	t[67] = s->trip_max_rpm_l;
	t[68] = s->trip_acc_cnt;
	t[69] = s->trip_brk_cnt;
	t[70] = s->trip_over_spd;
	t[71] = s->trip_idel_spd;
	t[72] = s->trip_sliding;
	t[73] = s->fast_time;
	t[74] = s->slow_time;
	t[75] = s->jam_time;
	t[76] = 0; // s->dtc_num;
	pthread_mutex_unlock(&s->lock);
}

/*保存行程数据到文件中*/
void saveDatatoFile(unsigned char *s, unsigned char *t, unsigned char *d, \
							int minCount, int dtc_count, int fileIndex)
{
	FILE * tripFile;
	unsigned char name[100];
	memset(name, 0, 100);

	sprintf(name,"%s%015d", CONFIG_TRIP_FILE_BASE, getFileIndex(&sdata));

	tripFile = fopen(name, "w+");
	//保存Slice数据
	SaveFile(tripFile, t, (minCount*MDATA_LEN));
	
	printf("Minutes count: %d mins \n", minCount);
	//保存Summary数据
	if(t[SDATA_LEN-1] > 0){
		/* ADD Summary Data to File Without DTC_NUM */
		SaveFile(tripFile, s, SDATA_LEN-1);
		/* ADD DTC CODE to File With DTC_NUM*/
		SaveFile(tripFile, d, dtc_count * DTC_LEN + 1);
	}
	else
		/* ADD Summary Data to File With DTC_NUM When DTC_NUM = 0 */
		SaveFile(tripFile, s, SDATA_LEN);
	fclose(tripFile);	
}

/*修改Config文件中的最后文件序号*/
/* 待添加  Index 文件修改 */
void saveFileIndexToConfigFile(int num)
{
	FILE * cfile;
	unsigned char configData[CONFIG_LENGTH];
	unsigned char indexData[INDEX_FILE_LENGTH];
	
	cfile = fopen(CONFIG_FILE, "r");
	/* Get Vehicle data from Config File */
	GetDataFromFile(cfile, configData, CONFIG_LENGTH);
	fclose(cfile);
	/* Add Last File Number to Config Buffer Data */
	AddLastRecordNumber(configData, num);
	/* CheckSum for Config File */	
	Add_Config_CheckSum(configData);
	/* Remove Old Config File */
	remove(CONFIG_FILE);
	/* Create New Config File */
	cfile = fopen(CONFIG_FILE, "w+");
	SaveFile(cfile, configData, CONFIG_LENGTH);
	fclose(cfile);

	/* 保存INDEX文件 */
	if( (cfile = fopen(INDEX_FILE, "r")) == NULL){	//如果index文件不存在
		 memset(indexData, 0x20, INDEX_FILE_LENGTH);
		 AddLastRecordNumberToIndex(indexData, num);
		 cfile = fopen(INDEX_FILE, "w+");
		 SaveFile(cfile, indexData, INDEX_FILE_LENGTH);
		 fclose(cfile);
	}
	else{	//如果index文件存在
		GetDataFromFile(cfile, indexData, INDEX_FILE_LENGTH);
		fclose(cfile);
		AddLastRecordNumberToIndex(indexData, num);
		remove(INDEX_FILE);
		cfile = fopen(INDEX_FILE, "w+");
		SaveFile(cfile, indexData, INDEX_FILE_LENGTH);
		fclose(cfile);
	}
}

/*计算线程入口函数*/
void * CalCarData(void *data)
{
	int i = 0;
	int index = 0;
	int tmp_data[SEC_DATA_LEN];
	int wait_data[60*SEC_DATA_LEN];
	
	int fast_time = 0;		// speed > 30Km
	int slow_time = 0;		// 5 < speed <= 30Km
	int jam_time = 0;		// speed <= 5Km

	while(1) {
		if(getTripStatus(&tstatus) == 1){	//引擎已经启动，开始行程数据记录
			/* Start to Read car data */
			memset(tmp_data, 0, SEC_DATA_LEN);
			/*从待计算缓存中读取数据切片*/
			readCarData(&cdata, tmp_data);	

			//如果数据中速度为-1，则表示引擎已经熄火，开始计算最后一个SLICE数据，并生成Summary数据
			if(tmp_data[OBD_DATA_SPD] == -1){
				/* Stop CalCalData Flag */
				stopTripDataRecord(&tstatus);
				/* if trip is finished, tmp_data[0] = -1, Calculation last MinData */
				calMinData(&rdata, index+1, wait_data);
				//Calculation Trip Summary
				convertMinData(&rdata, &mdata);
				/* Store Min Data into Trip Record Buffer */
				storeMinDataToTrip(&mdata, tstatus.trip_data, getMinIndex(&tstatus));
				/* Increase Min Index */
				increaseMinIndex(&tstatus);
				/* Create Trip Summary Data*/
				createTripSummary(&sdata, tstatus.trip_data, getMinIndex(&tstatus), \
											fast_time, slow_time, jam_time);
				/* Store Trip Summary Data to Trip Summary Byte Buffer*/
				storeSummaryDataToTrip(&sdata, tstatus.trip_summary);
				/* Save Min Data and Trip Summary to File */
				saveDatatoFile(tstatus.trip_summary, tstatus.trip_data, tstatus.dtc_data, \
										getMinIndex(&tstatus), getDTCnum(&tstatus),getFileIndex(&sdata));
				/* Save Last File Index to Config File */
				saveFileIndexToConfigFile(getFileIndex(&sdata));
				/* Increase File Index for Next Trip */
				updateFileIndex(&sdata, getFileIndex(&sdata) + 1);
				/* Clear Index of Min data */
				clearMinIndex(&tstatus);

				//play sound of New Data
				saveSoundList(&sl, SOUND_NEWDATA_INDEX, Sound_status);
				fast_time = 0;
				slow_time = 0;
				jam_time = 0;
			}
			else{
				if(tmp_data[OBD_DATA_SPD] > 30) fast_time++;
				else if( tmp_data[OBD_DATA_SPD] > 5 && tmp_data[OBD_DATA_SPD] <= 30) slow_time++;
				else	jam_time++;
 
				for(i = 0; i< SEC_DATA_LEN; i++){
					//此处 wait_data其实是一个二维数组，保存60个秒级数据切片
					wait_data[index*SEC_DATA_LEN + i] = tmp_data[i];
				}
				//如数据记录了60条即1分钟，则进行slice数据转换
				if( (index+1) % 60 == 0 ){
					//通过秒级数据切片计算分钟级数据切片的数据
					calMinData(&rdata, index+1, wait_data);
					//Calculation Slice Data
					convertMinData(&rdata, &mdata);
					//Store Min Data into Trip Record Buffer
					storeMinDataToTrip(&mdata, tstatus.trip_data, getMinIndex(&tstatus));
					//Increase Min index
					increaseMinIndex(&tstatus);
					printf("New Second Start \n");
					index = 0;
				}
				else index++;
			}
		}
		else{		//计算进程休眠
			sleep(1);
			index = 0;
  		   fast_time = 0;
			slow_time = 0;
			jam_time = 0;
		}
	}
}

